/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.datatheorem.ohos.trustkit.demoapp.slice;

import com.datatheorem.ohos.trustkit.TrustKit;
import com.datatheorem.ohos.trustkit.demoapp.PinningFailureReportCommonEventSubscriber;
import com.datatheorem.ohos.trustkit.demoapp.ResourceTable;


import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Text;
import ohos.agp.utils.Point;
import ohos.agp.window.service.Display;
import ohos.agp.window.service.DisplayManager;
import ohos.app.dispatcher.TaskDispatcher;
import ohos.app.dispatcher.task.TaskPriority;
import ohos.event.commonevent.CommonEventManager;
import ohos.event.commonevent.CommonEventSubscribeInfo;
import ohos.event.commonevent.MatchingSkills;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.global.resource.NotExistException;
import ohos.global.resource.WrongTypeException;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.rpc.RemoteException;


import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Optional;

import javax.net.ssl.HttpsURLConnection;

/**
 * DemoMainAbilitySlice
 *
 * @since 2021-03-22
 */
public class DemoMainAbilitySlice extends AbilitySlice {
    /**
     * 定义日志标签
     */
    public static final HiLogLabel DEBUG_TAG = new HiLogLabel(HiLog.LOG_APP, 0x00201, "TrustKit-Demo");
    /**
     * DATATHEOREM url
     */
    public static final int DATATHEOREM = 1;
    /**
     * GOOGLE url
     */
    public static final int GOOGLE = 2;

    private TaskDispatcher globalTaskDispatcher;
    private Text textView;
    private Boolean dialogisshow = false;
    private Text settings;
    private Point pt;


    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        globalTaskDispatcher = getGlobalTaskDispatcher(TaskPriority.DEFAULT);
        init();

        String event = "com.my.test";
        MatchingSkills matchingSkills = new MatchingSkills();
        matchingSkills.addEvent(event);
        /** 自定义事件 */
        /** matchingSkills.addEvent(CommonEventSupport.COMMON_EVENT_SCREEN_ON);  */
        /** 亮屏事件 */

        CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(matchingSkills);
        PinningFailureReportCommonEventSubscriber subscriber = new PinningFailureReportCommonEventSubscriber(subscribeInfo);
        try {
            CommonEventManager.subscribeCommonEvent(subscriber);
        } catch (RemoteException e) {
            HiLog.error(DEBUG_TAG, "Exception occurred during subscribeCommonEvent invocation.");
        }
    }

    public void init() {
        Optional<Display> display = DisplayManager.getInstance().getDefaultDisplay(this.getContext());
        pt = new Point();
        display.get().getSize(pt);

        EventRunner runner = EventRunner.create(true);
        DownloadWebpageHandler mDownloadWebpageHandler = new DownloadWebpageHandler(runner);

        DirectionalLayout toolbar = (DirectionalLayout) findComponentById(ResourceTable.Id_toolbar);
        textView = (Text) findComponentById(ResourceTable.Id_textview);
        settings = (Text) findComponentById(ResourceTable.Id_tv_settings);

        toolbar.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                dialogShow(true);
            }
        });
        settings.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                dialogShow(true);
            }
        });

        /** Initialize TrustKit with the default path for the Network Security Configuration which is */
        /** res/xml/network_security_config.xml */
        TrustKit.initializeWithNetworkSecurityConfiguration(this);

        // Connect to the URL with valid pins - this connection will succeed


        globalTaskDispatcher.asyncDispatch(new Runnable() {
            @Override
            public void run() {
                try {
                    String string = downLoad(getResourceManager().getElement(ResourceTable.String_datatheorem_url).getString());
                    InnerEvent event = InnerEvent.get(DATATHEOREM, 0L, string);
                    mDownloadWebpageHandler.sendEvent(event);
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (NotExistException e) {
                    e.printStackTrace();
                } catch (WrongTypeException e) {
                    e.printStackTrace();
                }
            }
        });

        // Connect to the URL with invalid pins - this connection will fail
        globalTaskDispatcher.asyncDispatch(new Runnable() {
            @Override
            public void run() {
                try {
                    String string = downLoad(getResourceManager().getElement(ResourceTable.String_google_url).getString());
                    InnerEvent event = InnerEvent.get(GOOGLE, 0L, string);
                    mDownloadWebpageHandler.sendEvent(event);
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (NotExistException e) {
                    e.printStackTrace();
                } catch (WrongTypeException e) {
                    e.printStackTrace();
                }
            }
        });
        findComponentById(ResourceTable.Id_dependentLayout).setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                dialogShow(false);
            }
        });
        findComponentById(ResourceTable.Id_dl_title).setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                dialogShow(false);
            }
        });
        textView.setText("Connection results are in the logs");
    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    protected void onBackground() {
        super.onBackground();
        TrustKit.cleanTrustKit();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }

    private void dialogShow(boolean isCanShow) {
        if (dialogisshow) {
            settings.createAnimatorProperty().alphaFrom(1).alpha(0).moveFromX(pt.getPointX() - settings.getWidth() - (pt.getPointX() / 40))
                .moveToX(pt.getPointX()).start();
            dialogisshow = false;
        } else {
            if (isCanShow) {
                settings.createAnimatorProperty().alphaFrom(0).alpha(1).moveFromX(pt.getPointX()).moveToX(pt.getPointX() - settings.getWidth() - (pt.getPointX() / 40)).setDelay(50).start();
                dialogisshow = true;
            }
        }
    }

    private String downLoad(String webUrl) {
        try {
            URL url = new URL(webUrl);
            HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
            connection.setSSLSocketFactory(TrustKit.getInstance().getSSLSocketFactory(url.getHost()));
            InputStream inputStream = connection.getInputStream();
        } catch (MalformedURLException e) {
            e.printStackTrace();
            return "Failed to connect to: ";
        } catch (IOException e) {
            e.printStackTrace();
            return "Failed to connect to: " + webUrl;
        }
        return "Successfully connected to: " + webUrl;
    }

    private static class DownloadWebpageHandler extends EventHandler {
        public DownloadWebpageHandler(EventRunner runner) {
            super(runner);
        }

        @Override
        protected void processEvent(InnerEvent event) {
            super.processEvent(event);
            if (event == null) {
                return;
            }
            int mEventId = event.eventId;
            switch (mEventId) {
                case DATATHEOREM:
                    HiLog.info(DEBUG_TAG, (String) event.object);
                    return;
                case GOOGLE:
                    HiLog.info(DEBUG_TAG, (String) event.object);
                    return;
                default:
                    throw new IllegalStateException("Unexpected value: " + event.eventId);
            }
        }
    }
}
